﻿/***************************************************************************
	Copyright (C) 2010 RapidWebDev Organization (Author: Eunge, Legal Name: Jian Liu, Email: eunge.liu@gmail.com)

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
 ***************************************************************************/

using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using BaoJianSoft.Common;
using BaoJianSoft.Membership;
using BaoJianSoft.Web.Extensions;
using BaoJianSoft.Web.Extensions.Controls;
using Spring.Core;
using Spring.Expressions;
using Spring.Expressions.Processors;
using BaoJianSoft.Web.Extensions.Properties;

namespace BaoJianSoft.Web.Extensions.DynamicPages
{
    /// <summary>
    /// Query section panel
    /// </summary>
    public class QueryPanel : Panel, INamingContainer
    {
        private readonly static Regex urlMaskSplitter = new Regex(@"\$[^\$]+\$", RegexOptions.Compiled);

        private bool wrappedWithContainer;
        private LButton buttonQuery;
        private Collection<TextBox> queryableTextBoxes = new Collection<TextBox>();
        private Collection<RadioButtonList> queryableRadioButtonLists = new Collection<RadioButtonList>();
        private Collection<DropDownList> queryableDropDownLists = new Collection<DropDownList>();
        private Collection<DateTimeControl[]> queryableDateControls = new Collection<DateTimeControl[]>();

        /// <summary>
        /// The event fires when query button is clicked.
        /// </summary>
        public event EventHandler<QueryEventArgs> Querying;

        /// <summary>
        /// Set/get query section building configuration.
        /// </summary>
        public QueryConfiguration Configuration { get; set; }

        /// <summary>
        /// Sets/gets query event argument mapping to current querying form.
        /// </summary>
        public QueryEventArgs CurrentQueryEventArgs
        {
            get
            {
                return this.GenerateQueryEventArgs();
            }
            set
            {
                Kit.NotNull(value, "value");
                this.SetQueryEventArgsToControls(value);
            }
        }

        /// <summary>
        /// 是否显示查询按钮
        /// </summary>
        public bool DisplayQueryButton
        {
            get { if (base.ViewState["DisplayQueryButton"] == null) return true; return (bool)base.ViewState["DisplayQueryButton"]; }
            set { base.ViewState["DisplayQueryButton"] = value; }
        }

        /// <summary>
        /// Construct QueryPanel instance
        /// </summary>
        public QueryPanel() : this(true) { }

        /// <summary>
        /// Construct QueryPanel instance
        /// </summary>
        /// <param name="wrappedWithContainer"></param>
        public QueryPanel(bool wrappedWithContainer)
        {
            this.wrappedWithContainer = wrappedWithContainer;
        }

        /// <summary>
        /// 重新执行查询，适合于在对CurrentQueryEventArgs设置了值以后
        /// </summary>
        public override void DataBind()
        {
            base.DataBind();

            if (this.Querying != null)
                this.Querying(this, this.CurrentQueryEventArgs);
        }

        /// <summary>
        /// Raises the System.Web.UI.Control.Init event.
        /// </summary>
        /// <param name="e"></param>
        protected override void OnInit(EventArgs e)
        {
            if (this.Configuration == null) throw new InvalidProgramException(Resources.PropertyConfigurationIsNull);

            base.OnInit(e);

            this.BuildQueryPanel();
        }

        /// <summary>
        /// 判断是否显示查询按钮
        /// </summary>
        /// <param name="e"></param>
        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);

            if (!this.DisplayQueryButton) this.buttonQuery.Visible = false;
        }

        private void BuildQueryPanel()
        {
            if (this.Configuration.Fields.Count() == 0) return;

            List<HtmlTableRow> tableRowsToAdd = new List<HtmlTableRow>();
            int columnIndex = 0;
            HtmlTableRow tableRow = new HtmlTableRow();
            HtmlTableCell tableCellLabel = null;
            HtmlTableCell tableCellField = null;
            var iterator = this.Configuration.Fields.GetEnumerator();

            #region foreach to build queryable field control

            while (iterator.MoveNext())
            {
                QueryableField queryableField = iterator.Current;
                if ((columnIndex + queryableField.ControlCount - 1) > 2)
                {
                    columnIndex = queryableField.ControlCount;
                    tableRowsToAdd.Add(tableRow);
                    tableRow = new HtmlTableRow();
                }
                else
                {
                    columnIndex += queryableField.ControlCount;
                }

                tableCellLabel = new HtmlTableCell("td");
                tableCellLabel.Attributes["class"] = "c1";
                tableCellLabel.NoWrap = true;
                tableCellLabel.InnerText = queryableField.Label;
                tableRow.Cells.Add(tableCellLabel);

                tableCellField = new HtmlTableCell("td");
                tableCellField.Attributes["class"] = "c2";
                tableRow.Cells.Add(tableCellField);

                switch (queryableField.ControlType)
                {
                    case QueryableControlTypes.Text:
                        {
                            TextBox textboxField = new TextBox()
                            {
                                ID = string.Format("TextBox_{0}", FormatFieldName(queryableField.FieldName)),
                                CssClass = "textbox150"
                            };

                            textboxField.Attributes["fieldname"] = queryableField.FieldName;
                            this.queryableTextBoxes.Add(textboxField);
                            tableCellField.Controls.Add(textboxField);

                            if (queryableField.SelectionIcon != null)
                            {
                                tableCellField.Controls.Add(new HtmlGenericControl("span") { InnerText = " " });
                                tableCellField.Controls.Add(GenerateQueryableFieldSelectionIcon(textboxField.ClientID, queryableField.SelectionIcon));
                            }

                            break;
                        }
                    case QueryableControlTypes.RadioButtonList:
                        {
                            RadioButtonList radioButtonListField = new RadioButtonList()
                            {
                                ID = string.Format("RadioButtonList_{0}", FormatFieldName(queryableField.FieldName)),
                                RepeatDirection = RepeatDirection.Horizontal,
                                RepeatLayout = RepeatLayout.Flow
                            };

                            radioButtonListField.Attributes["fieldname"] = queryableField.FieldName;
                            radioButtonListField.Items.Clear();

                            if (queryableField.DefaultValue != null)
                            {
								string defaultOptionText = !Kit.IsEmpty(queryableField.DefaultValue.DefaultOptionText) ? queryableField.DefaultValue.DefaultOptionText : Resources.All;
                                radioButtonListField.Items.Insert(0, new ListItem("<span style=\"color:blue\">" + defaultOptionText + "</span>", ""));

                                if (queryableField.DefaultValue.Options != null)
                                {
                                    string selectedValue = "";
                                    foreach (Option option in queryableField.DefaultValue.Options)
                                    {
                                        if (option.Selected) selectedValue = option.Value;
                                        radioButtonListField.Items.Add(new ListItem()
                                        {
                                            Text = option.Text,
                                            Value = option.Value
                                        });
                                    }

                                    if (!Page.IsPostBack) radioButtonListField.SelectedValue = selectedValue;
                                }
                                else if (queryableField.DefaultValue.OptionsCallback != null)
                                {
                                    string selectedValue = "";
                                    foreach (Option option in queryableField.DefaultValue.OptionsCallback.Read())
                                    {
                                        if (option.Selected) selectedValue = option.Value;
                                        radioButtonListField.Items.Add(new ListItem()
                                        {
                                            Text = option.Text,
                                            Value = option.Value
                                        });
                                    }

                                    if (!Page.IsPostBack) radioButtonListField.SelectedValue = selectedValue;
                                }
                            }

                            this.queryableRadioButtonLists.Add(radioButtonListField);
                            tableCellField.Controls.Add(radioButtonListField);
                            break;
                        }
                    case QueryableControlTypes.DropDownList:
                        {
                            DropDownList dropdownlistField = new DropDownList()
                            {
                                ID = string.Format("DropDownList_{0}", FormatFieldName(queryableField.FieldName)),
                                Width = new Unit("154px"),
                            };

                            dropdownlistField.Attributes["fieldname"] = queryableField.FieldName;
                            dropdownlistField.Items.Clear();

                            if (queryableField.DefaultValue != null)
                            {
                                if (queryableField.DefaultValue.Options != null)
                                {
                                    string defaultOptionText = !Kit.IsEmpty(queryableField.DefaultValue.DefaultOptionText) ? queryableField.DefaultValue.DefaultOptionText : Resources.All;
                                    dropdownlistField.Items.Insert(0, new ListItem(defaultOptionText, ""));

                                    string selectedValue = "";
                                    foreach (Option option in queryableField.DefaultValue.Options)
                                    {
                                        if (option.Selected) selectedValue = option.Value;
                                        dropdownlistField.Items.Add(new ListItem()
                                        {
                                            Text = option.Text,
                                            Value = option.Value
                                        });
                                    }

                                    if (!Page.IsPostBack) dropdownlistField.SelectedValue = selectedValue;
                                }
                                else if (queryableField.DefaultValue.OptionsCallback != null)
                                {
                                    string selectedValue = "";
                                    foreach (Option option in queryableField.DefaultValue.OptionsCallback.Read())
                                    {
                                        if (option.Selected) selectedValue = option.Value;
                                        dropdownlistField.Items.Add(new ListItem()
                                        {
                                            Text = option.Text,
                                            Value = option.Value
                                        });
                                    }

                                    if (!Page.IsPostBack) dropdownlistField.SelectedValue = selectedValue;
                                }
                            }

                            this.queryableDropDownLists.Add(dropdownlistField);
                            tableCellField.Controls.Add(dropdownlistField);
                            break;
                        }

                    case QueryableControlTypes.Date:
                        DateTimeControlDefaultValues beginDate = DateTimeControlDefaultValues.None;
                        DateTimeControlDefaultValues endDate = DateTimeControlDefaultValues.None;
                        if (queryableField.DefaultValue != null)
                        {
                            beginDate = queryableField.DefaultValue.BeginDate;
                            endDate = queryableField.DefaultValue.EndDate;
                        }

                        DateTimeControl[] dateControlArray = new DateTimeControl[2];
                        dateControlArray[0] = new DateTimeControl() { ID = string.Format("Date_{0}_0", FormatFieldName(queryableField.FieldName)), DefaultValue = beginDate, ExtensionData = queryableField.FieldName, ControlType = DateTimeControlType.Date };
                        dateControlArray[1] = new DateTimeControl() { ID = string.Format("Date_{0}_1", FormatFieldName(queryableField.FieldName)), DefaultValue = endDate, ExtensionData = queryableField.FieldName, ControlType = DateTimeControlType.Date, AddedOneDay = true };
                        tableCellLabel.InnerText = string.Format(queryableField.Label, "起");
                        tableCellField.Controls.Add(dateControlArray[0]);

                        tableCellLabel = new HtmlTableCell("td");
                        tableCellLabel.Attributes["class"] = "c1";
                        tableCellLabel.NoWrap = true;
                        tableCellLabel.InnerText = string.Format(queryableField.Label, "止");
                        tableRow.Cells.Add(tableCellLabel);

                        tableCellField = new HtmlTableCell("td");
                        tableCellField.Attributes["class"] = "c2";
                        tableCellField.Controls.Add(dateControlArray[1]);
                        tableRow.Cells.Add(tableCellField);

                        this.queryableDateControls.Add(dateControlArray);
                        break;
                }

                // render next controls into break line.
                if (iterator.Current.BreakLine)
                {
                    tableCellField.ColSpan = 7 - columnIndex * 2;
                    tableCellField.Attributes["class"] = "span";
                    columnIndex = int.MaxValue;
                }
            }

            #endregion

            int reservedColumns = 7 - columnIndex * 2;
            if (reservedColumns > 1)
            {
                tableCellField.ColSpan = reservedColumns;
                tableCellField.Attributes["class"] = "span";
            }

            tableRowsToAdd.Add(tableRow);

            if (tableRowsToAdd.Count > 0)
            {
                this.buttonQuery = new LButton() { ID = "ButtonQuery", Text = Resources.QueryButtonText };
                WebUtility.RegisterAsyncPostBackControl(buttonQuery);
                Panel container = null;
                if (this.wrappedWithContainer)
                    container = new Container { DefaultButton = buttonQuery.ID };
                else
                    container = new Panel { DefaultButton = buttonQuery.ID };

                this.Controls.Add(container);

                HtmlGenericControl h4 = new HtmlGenericControl("h4") { InnerHtml = this.Configuration.HeaderText };
                container.Controls.Add(h4);

                HtmlTable table = new HtmlTable() { CellPadding = 0, CellSpacing = 0, Width = "100%" };
                container.Controls.Add(table);
                table.Attributes["class"] = "table6col";

                foreach (HtmlTableRow tableRowToAdd in tableRowsToAdd) table.Rows.Add(tableRowToAdd);

                HtmlTableRow tableRowButton = new HtmlTableRow();
                table.Rows.Add(tableRowButton);

                HtmlTableCell tableCellButton = new HtmlTableCell("td") { ColSpan = 6, Align = "center" };
                tableCellButton.Controls.Add(buttonQuery);
                tableRowButton.Cells.Add(tableCellButton);

                buttonQuery.Click += new EventHandler(buttonQuery_Click);

                this.DefaultButton = "ButtonQuery";
            }
        }

        private void buttonQuery_Click(object sender, EventArgs e)
        {
            if (this.Querying == null) return;
            this.Querying(this, this.CurrentQueryEventArgs);
        }

        private QueryEventArgs GenerateQueryEventArgs()
        {
            List<QueryCriteria> criterias = new List<QueryCriteria>();
            int parameterIndex = 0;
            ArrayList parameters = new ArrayList();
            StringBuilder predicateBuilder = new StringBuilder();
            foreach (TextBox textbox in this.queryableTextBoxes)
            {
                if (textbox.Text.Trim().Length > 0)
                {
                    if (predicateBuilder.Length > 0) predicateBuilder.Append(" && ");
                    predicateBuilder.AppendFormat("{0}.Contains(@{1})", textbox.Attributes["fieldname"], parameterIndex++);
                    parameters.Add(textbox.Text.Trim());
                    criterias.Add(new QueryCriteria { FieldName = textbox.Attributes["fieldname"], Value = textbox.Text.Trim(), ControlType = QueryableControlTypes.Text });
                }
            }

            foreach (RadioButtonList radioButtonList in this.queryableRadioButtonLists)
            {
                if (!Kit.IsEmpty(radioButtonList.SelectedValue))
                {
                    if (predicateBuilder.Length > 0) predicateBuilder.Append(" && ");
                    string fieldName = radioButtonList.Attributes["fieldname"];
                    QueryableField queryableField = this.Configuration.Fields.Where(f => f.FieldName.Equals(fieldName)).FirstOrDefault();
                    predicateBuilder.AppendFormat("{0}==@{1}", radioButtonList.Attributes["fieldname"], parameterIndex++);
                    object parameterValue = ChangeType(radioButtonList.SelectedValue, queryableField.FieldType);
                    parameters.Add(parameterValue);
                    criterias.Add(new QueryCriteria { FieldName = radioButtonList.Attributes["fieldname"], Value = parameterValue, ControlType = QueryableControlTypes.RadioButtonList });
                }
            }

            foreach (DropDownList dropdownlist in this.queryableDropDownLists)
            {
                if (!Kit.IsEmpty(dropdownlist.SelectedValue))
                {
                    if (predicateBuilder.Length > 0) predicateBuilder.Append(" && ");
                    string fieldName = dropdownlist.Attributes["fieldname"];
                    QueryableField queryableField = this.Configuration.Fields.Where(f => f.FieldName.Equals(fieldName)).FirstOrDefault();
                    predicateBuilder.AppendFormat("{0}==@{1}", dropdownlist.Attributes["fieldname"], parameterIndex++);
                    object parameterValue = ChangeType(dropdownlist.SelectedValue, queryableField.FieldType);
                    parameters.Add(parameterValue);
                    criterias.Add(new QueryCriteria { FieldName = dropdownlist.Attributes["fieldname"], Value = parameterValue, ControlType = QueryableControlTypes.DropDownList });
                }
            }

            foreach (DateTimeControl[] dateControlArray in queryableDateControls)
            {
                if (dateControlArray[0].SelectedDate.HasValue)
                {
                    if (predicateBuilder.Length > 0) predicateBuilder.Append(" && ");
                    predicateBuilder.AppendFormat("{0}>=@{1}", dateControlArray[0].ExtensionData, parameterIndex++);
                    parameters.Add(dateControlArray[0].SelectedDate);
                    criterias.Add(new QueryCriteria { FieldName = dateControlArray[0].ExtensionData, Value = dateControlArray[0].SelectedDate, ControlIndex = 0, ControlType = QueryableControlTypes.Date });
                }

                if (dateControlArray[1].SelectedDate.HasValue)
                {
                    if (predicateBuilder.Length > 0) predicateBuilder.Append(" && ");
                    predicateBuilder.AppendFormat("{0}<@{1}", dateControlArray[1].ExtensionData, parameterIndex++);
                    parameters.Add(dateControlArray[1].SelectedDate);
                    criterias.Add(new QueryCriteria { FieldName = dateControlArray[1].ExtensionData, Value = dateControlArray[1].SelectedDate, ControlIndex = 1, ControlType = QueryableControlTypes.Date });
                }
            }

            string predicate = predicateBuilder.Length > 0 ? predicateBuilder.ToString() : null;
            object[] parameterValues = parameters.Count > 0 ? parameters.ToArray() : null;

            return new QueryEventArgs(criterias, predicate, parameterValues);
        }

        private void SetQueryEventArgsToControls(QueryEventArgs e)
        {
            QueryCriteria queryCriteria = null;
            foreach (TextBox textbox in this.queryableTextBoxes)
            {
                queryCriteria = e.Criterias.FirstOrDefault(c => c.ControlType == QueryableControlTypes.Text && c.FieldName == textbox.Attributes["fieldname"]);
                string textboxValue = queryCriteria == null ? "" : queryCriteria.Value.ToString();
                textbox.Text = textboxValue;
            }

            foreach (RadioButtonList radioButtonList in this.queryableRadioButtonLists)
            {
                queryCriteria = e.Criterias.FirstOrDefault(c => c.ControlType == QueryableControlTypes.RadioButtonList && c.FieldName == radioButtonList.Attributes["fieldname"]);
                if (queryCriteria == null || radioButtonList.Items.FindByValue(queryCriteria.Value.ToString()) == null)
                    radioButtonList.SelectedIndex = -1;
                else
                    radioButtonList.SelectedValue = queryCriteria.Value.ToString();
            }

            foreach (DropDownList dropDownList in this.queryableDropDownLists)
            {
                queryCriteria = e.Criterias.FirstOrDefault(c => c.ControlType == QueryableControlTypes.DropDownList && c.FieldName == dropDownList.Attributes["fieldname"]);
                if (queryCriteria == null || dropDownList.Items.FindByValue(queryCriteria.Value.ToString()) == null)
                    dropDownList.SelectedIndex = -1;
                else
                    dropDownList.SelectedValue = queryCriteria.Value.ToString();
            }

            foreach (DateTimeControl[] dateControls in this.queryableDateControls)
            {
                string fieldName = dateControls.First().ExtensionData;
                int controlIndex = !dateControls[0].AddedOneDay ? 0 : 1;
                queryCriteria = e.Criterias.FirstOrDefault(c => c.ControlType == QueryableControlTypes.Date && c.FieldName == fieldName && c.ControlIndex == controlIndex);
                if (queryCriteria != null)
                    dateControls[0].SelectedDate = CalculateExactDateTime(queryCriteria.Value as DateTime?, dateControls[0].AddedOneDay);
                else
                    dateControls[0].SelectedDate = null;

                controlIndex = !dateControls[1].AddedOneDay ? 0 : 1;
                queryCriteria = e.Criterias.FirstOrDefault(c => c.ControlType == QueryableControlTypes.Date && c.FieldName == fieldName && c.ControlIndex == controlIndex);
                if (queryCriteria != null)
                    dateControls[1].SelectedDate = CalculateExactDateTime(queryCriteria.Value as DateTime?, dateControls[1].AddedOneDay);
                else
                    dateControls[1].SelectedDate = null;
            }
        }

        private static string FormatFieldName(string fieldName)
        {
            return fieldName.Replace(".", "__").Replace("\"", "_").Replace("[", "").Replace("]", "");
        }

        private static object ChangeType(string stringValue, Type targetType)
        {
            try
            {
                return Convert.ChangeType(stringValue, targetType);
            }
            catch
            {
            }

            if (targetType.IsSubclassOf(typeof(Enum)))
            {
                try
                {
                    return Enum.Parse(targetType, stringValue);
                }
                catch
                {
                }
            }

            ConstructorInfo constructor = targetType.GetConstructor(new Type[] { typeof(string) });
            if (constructor != null)
            {
                try
                {
                    return constructor.Invoke(new object[] { stringValue });
                }
                catch
                {
                }
            }

            MethodInfo method = targetType.GetMethod("Parse", new Type[] { typeof(string) });
            if (method != null)
            {
                try
                {
                    return method.Invoke(null, new object[] { stringValue });
                }
                catch
                {
                }
            }

            throw new NotSupportedException(string.Format("Attemption to convert string value {0} to {1} failed.", stringValue, targetType));
        }

        private static Control GenerateQueryableFieldSelectionIcon(string callbackTextBoxClientId, QueryFieldSelectionIcon queryfieldSelectionIcon)
        {
            string pageUrl = BuildPopupPageUrl(callbackTextBoxClientId, queryfieldSelectionIcon);
            string javascript = WebUtility.GeneratePopupWindowJs(pageUrl, queryfieldSelectionIcon.PopupPageWidth, queryfieldSelectionIcon.PopupPageHeight);

            Image selectionIcon = new Image()
            {
                ImageUrl = !Kit.IsEmpty(queryfieldSelectionIcon.ImageUrl) ? queryfieldSelectionIcon.ImageUrl : GetDefaultSelectionIconUrl(),
                AlternateText = Resources.IconSelectionToolTip,
				ToolTip = Resources.IconSelectionToolTip
            };

            HtmlGenericControl span = new HtmlGenericControl("span");
            span.Style.Add("cursor", "pointer");
            span.Attributes.Add("onclick", "javascript:" + javascript);
            span.Controls.Add(selectionIcon);

            return span;
        }

        /// <summary>
        /// Build popup page url with replacing all variables in popup page url mask.
        /// </summary>
        /// <param name="callbackTextBoxClientId"></param>
        /// <param name="queryfieldSelectionIcon"></param>
        /// <returns></returns>
        private static string BuildPopupPageUrl(string callbackTextBoxClientId, QueryFieldSelectionIcon queryfieldSelectionIcon)
        {
            string popupPageUrl = queryfieldSelectionIcon.PopupPageUrlMask;
            MatchCollection matchCollection = urlMaskSplitter.Matches(queryfieldSelectionIcon.PopupPageUrlMask);
            if (matchCollection.Count > 0)
            {
                IAuthenticationContext authenticationContext = SpringContext.Current.GetObject<IAuthenticationContext>();
                foreach (Match match in matchCollection)
                {
                    string matchedValue = match.Value.Substring(1, match.Value.Length - 2);
                    if (matchedValue.StartsWith("AuthenticationContext"))
                    {
                        try
                        {
                            string propertyAccessor = matchedValue.Substring("AuthenticationContext".Length);
                            if (propertyAccessor.StartsWith(".")) propertyAccessor = propertyAccessor.Substring(1);
                            object expressionValue = ExpressionEvaluator.GetValue(authenticationContext, propertyAccessor);
                            string variableValue = expressionValue != null ? expressionValue.ToString() : "";
                            popupPageUrl = popupPageUrl.Replace(match.Value, variableValue);
                        }
                        catch (InvalidPropertyException exp)
                        {
                            Logger.Instance(typeof(QueryPanel)).Error(exp);
                            throw;
                        }
                    }
                }
            }

            if (popupPageUrl.Contains('?')) popupPageUrl += "&";
            popupPageUrl += "OpenerCallbackControlId=" + Kit.UrlEncode(callbackTextBoxClientId);
            popupPageUrl += string.Format("&AppendSelectedValue={0}", queryfieldSelectionIcon.AllowMultipleSelected);
            return popupPageUrl;
        }

        private static string GetDefaultSelectionIconUrl()
        {
            Page page = HttpContext.Current.Handler as Page;
            return string.Format("{0}/App_Themes/{1}/Images/query.png", WebUtility.WebSiteBaseUrl, page.Theme);
        }

        private static DateTime? CalculateExactDateTime(DateTime? dtm, bool addedOneDay)
        {
            if (dtm == null) return dtm;
            if (!addedOneDay) return dtm;

            return dtm.Value.AddDays(-1);
        }
    }
}
